/**  
 * All rights Reserved, Designed By www.tydic.com
 * @Title:  OrderServiceImpl.java   
 * @Package com.axin.service.impl   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: axin     
 * @date:   2019年4月9日 下午11:03:28   
 * @version V1.0 
 * @Copyright: 2019 www.hao456.top Inc. All rights reserved. 
 */
package com.axin.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.axin.common.entity.ApiToken;
import com.axin.common.entity.request.CreateOrderRequest;
import com.axin.common.entity.request.IntrustOrdersDetailRequest;
import com.axin.common.entity.response.ApiResponse;
import com.axin.common.entity.response.Batchcancel;
import com.axin.common.entity.response.BatchcancelBean;
import com.axin.common.entity.response.BatchcancelResponse;
import com.axin.common.entity.response.BatchcancelResult;
import com.axin.common.entity.response.IntrustDetail;
import com.axin.common.entity.response.IntrustDetailResponse;
import com.axin.common.entity.response.MatchresultsOrdersDetail;
import com.axin.common.entity.response.MatchresultsOrdersDetailResponse;
import com.axin.common.entity.response.OrdersDetail;
import com.axin.common.entity.response.OrdersDetailResponse;
import com.axin.common.entity.response.SubmitcancelResponse;
import com.axin.common.exception.ParamIllegalException;
import com.axin.common.huobi.HttpRequest;
import com.axin.entity.bo.BuyResult;
import com.axin.service.OrderService;
import com.fasterxml.jackson.core.type.TypeReference;

/**   
 * @Description: 订单服务层实现类 
 * @ClassName:  OrderServiceImpl
 * @author:  Axin 
 * @date:   2019年4月9日 下午11:03:28   
 * @Copyright: 2019 www.hao456.top Inc. All rights reserved. 
 */
@Service
public class OrderServiceImpl implements OrderService {

	
	@Autowired
	private HttpRequest httpRequest;
	//创建订单url
	@Value("${API_ORDER_CREATE_URL}")
	private String API_ORDER_CREATE_URL;
	
	@Value("${API_ORDER_PLACE_URL}")
	private String API_ORDER_PLACE_URL;
	
	/**订单祥情URL*/
	@Value("${API_ORDER_DETAIL_URL}")
	private String API_ORDER_DETAIL_URL;
	
	/**查询某个订单成交明细*/
	@Value("${API_ORDER_MATCHRESULTS_URL}")
	private String API_ORDER_MATCHRESULTS_URL;
	
	/**查询当前委托，历史委托*/
	@Value("${API_ORDER_ORDERS_URL}")
	private String API_ORDER_ORDERS_URL;
	
	/**取消订单*/
	@Value("${API_ORDER_CANCEL_URL}")
	private String API_ORDER_CANCEL_URL;
	
	/**根据订单id,批量撤消订单*/
	@Value("${API_ORDER_BATCHCANCEL_URL}")
	private String API_ORDER_BATCHCANCEL_URL;
	
	/**取消符合条件的订单*/
	@Value("${API_ORDER_CANCELORDERS_URL}")
	private String API_ORDER_CANCELORDERS_URL;
	
	
	
	
	
	@Override
	public Long createOrder(ApiToken token,CreateOrderRequest request) {
		ApiResponse<Long> resp =
				httpRequest.post(token,API_ORDER_CREATE_URL, request, new TypeReference<ApiResponse<Long>>() {
                });
		return resp.checkAndReturn();
		
	}
	
	
	

	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#createBuyLimitOrder(com.axin.common.entity.ApiToken, com.axin.common.entity.request.CreateOrderRequest)
	 */
	@Override
	public Long createBuyOrder(ApiToken token, String symbol,Integer accountId,String amount,String price) {
		 CreateOrderRequest orderReq = new CreateOrderRequest();
         orderReq.accountId = String.valueOf(accountId);
         orderReq.amount = amount;
         orderReq.price = price;
         orderReq.symbol = symbol;
         orderReq.type = CreateOrderRequest.OrderType.BUY_LIMIT;
         orderReq.source = "api";
         Long orderId = createOrder(token, orderReq);
		return orderId;
	}


	
	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#createBuyMarketOrder(com.axin.common.entity.ApiToken, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public Long createBuyOrder(ApiToken token, String symbol, Integer accountId, String amount) {
		 CreateOrderRequest orderReq = new CreateOrderRequest();
         orderReq.accountId = String.valueOf(accountId);
         orderReq.amount = amount;
         orderReq.symbol = symbol;
         orderReq.type = CreateOrderRequest.OrderType.BUY_MARKET;
         orderReq.source = "api";
         Long orderId = createOrder(token, orderReq);
         return orderId;
	}

	
	

	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#createBuyOrderWithDetail(com.axin.common.entity.ApiToken, java.lang.String, java.lang.Integer, java.lang.String)
	 */
	@Override
	public BuyResult createBuyOrderWithDetail(ApiToken token, String symbol, Integer accountId, String money,int moneyScale, int amountScale) {
		
		Long orderId = null;
		String fieldAmount = null;//完成数量
		String fieldMoney = null;//完成金额
		String state = null;//状态
		String fieldFees = null;
		String createdAt = null;//订单创建时间
		
		//以当前市价购买
		orderId = createBuyOrder(token, symbol, accountId, money);
		try {
			Thread.sleep(3000);//延迟2秒查询订单
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//查询订单祥情
		OrdersDetail ordersDetail = ordersDetail(token, orderId);
		state = ordersDetail.getState();
		long createTime = ordersDetail.getCreatedAt();
		Date date = new Date(createTime);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		createdAt = sdf.format(date);
		if("filled".equals(state) || "partial-filled".equals(state)){
			//成交数量
			//BigDecimal fieldAmountBig = new BigDecimal(ordersDetail.getFieldAmount()).setScale(amountScale, BigDecimal.ROUND_DOWN);
			fieldAmount = ordersDetail.getFieldAmount();//初始化持仓数量
			
			//成交金额
			//BigDecimal fieldCashAmountBig = new BigDecimal(ordersDetail.getFieldCashAmount()).setScale(moneyScale, BigDecimal.ROUND_DOWN);//本次购买的总金额
			fieldMoney = ordersDetail.getFieldCashAmount();
			
			//BigDecimal fieldFeesBig = new BigDecimal(ordersDetail.getFieldFees());
			fieldFees = ordersDetail.getFieldFees();
			
			
		}else{
			//撤销未成交的订单
			SubmitcancelResponse submitcancel = submitcancel(token, orderId);
			
		}
		
		return new BuyResult(orderId,fieldAmount, fieldMoney, fieldFees,state,createdAt);
		
		
	}




	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#createSellLimitOrder(com.axin.common.entity.ApiToken, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public Long createSellOrder(ApiToken token, String symbol, Integer accountId, String amount, String price) {
		CreateOrderRequest orderReq = new CreateOrderRequest();
        orderReq.accountId = String.valueOf(accountId);
        orderReq.amount = amount;
        orderReq.price = price;
        orderReq.symbol = symbol;
        orderReq.type = CreateOrderRequest.OrderType.SELL_LIMIT;
        orderReq.source = "api";
        Long orderId = createOrder(token, orderReq);
		return orderId;
	}




	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#createSellMarketOrder(com.axin.common.entity.ApiToken, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public Long createSellOrder(ApiToken token, String symbol, Integer accountId, String amount) {
		CreateOrderRequest orderReq = new CreateOrderRequest();
        orderReq.accountId = String.valueOf(accountId);
        orderReq.amount = amount;
        orderReq.symbol = symbol;
        orderReq.type = CreateOrderRequest.OrderType.SELL_MARKET;
        orderReq.source = "api";
        Long orderId = createOrder(token, orderReq);
        return orderId;
	}




	@Override
	public String placeOrder(ApiToken token, long orderId) {
		String tempUrl = new String(API_ORDER_PLACE_URL); 
		String newUrl = tempUrl.replace("{order-id}", orderId+"");
		ApiResponse<String> resp = httpRequest.post(token,newUrl, null,
	                new TypeReference<ApiResponse<String>>() {
	                });
	    return resp.checkAndReturn();
		
	}



	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#ordersDetail(com.axin.common.entity.ApiToken, long)
	 */
	@Override
	public OrdersDetail ordersDetail(ApiToken token, long orderId) {
		String tempUrl = new String(API_ORDER_DETAIL_URL); 
		String newUrl = tempUrl.replace("{order-id}", orderId+"");
		OrdersDetailResponse<OrdersDetail> resp = httpRequest.get(token,newUrl, null, new TypeReference<OrdersDetailResponse<OrdersDetail>>() {});
		return resp.checkAndReturn();
	}



	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#matchresults(com.axin.common.entity.ApiToken, long)
	 */
	@Override
	public List<MatchresultsOrdersDetail> matchresults(ApiToken token, long orderId) {
		String tempUrl = new String(API_ORDER_MATCHRESULTS_URL); 
		String newUrl = tempUrl.replace("{order-id}", orderId+"");
		MatchresultsOrdersDetailResponse<List<MatchresultsOrdersDetail>> resp = 
				httpRequest.get(token,newUrl, null, new TypeReference<MatchresultsOrdersDetailResponse<List<MatchresultsOrdersDetail>>>() {});
		return resp.checkAndReturn();
	}



	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#intrustOrdersDetail(com.axin.common.entity.ApiToken, com.axin.common.entity.request.IntrustOrdersDetailRequest)
	 */
	@Override
	public List<IntrustDetail> getOrders(ApiToken token, IntrustOrdersDetailRequest req) {
		if(StringUtils.isEmpty(req.symbol)){
			throw new NullPointerException("symbol is null");
		}
		if(StringUtils.isEmpty(req.states)){
			throw new NullPointerException("states is null");
		}
		HashMap map = new HashMap();
        map.put("symbol", req.symbol);
        map.put("states", req.states);
       
         if (StringUtils.isNotEmpty(req.startDate)) {
             map.put("start-date",req.startDate);
  		}
         if (StringUtils.isNotEmpty(req.endDate)) {
             map.put("end-date",req.endDate);
  		}
         if (StringUtils.isNotEmpty(req.types)) {
             map.put("types",req.types);
  		}
         if (StringUtils.isNotEmpty(req.from)) {
             map.put("from",req.from);
  		}
         if (StringUtils.isNotEmpty(req.direct)) {
             map.put("direct",req.direct);
  		}
         if (StringUtils.isNotEmpty(req.size)) {
             map.put("size",req.size);
  		}
        IntrustDetailResponse<List<IntrustDetail>> resp = 
        				httpRequest.get(token,API_ORDER_ORDERS_URL,
        								map, 
        								new TypeReference<IntrustDetailResponse<List<IntrustDetail>>>() {});
		return resp.checkAndReturn();
	}




	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#submitcancel(com.axin.common.entity.ApiToken, long)
	 */
	@Override
	public SubmitcancelResponse submitcancel(ApiToken token, long orderId) {
		String tempUrl = new String(API_ORDER_CANCEL_URL); 
		String newUrl = tempUrl.replace("{order-id}", orderId+"");
		SubmitcancelResponse resp = httpRequest.post(token,newUrl, null, new TypeReference<SubmitcancelResponse>() {
        });
        return resp;
	}




	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#submitcancel(com.axin.common.entity.ApiToken, java.util.List)
	 */
	@Override
	public Batchcancel submitcancel(ApiToken token, List orderIds) {
		 Map<String, List> parameterMap = new HashMap();
         parameterMap.put("order-ids", orderIds);
         BatchcancelResponse<Batchcancel<List<String>, List<BatchcancelBean>>> resp =
        		 httpRequest.post(token,API_ORDER_BATCHCANCEL_URL, parameterMap, new TypeReference<BatchcancelResponse<Batchcancel<List<String>, List<BatchcancelBean>>>>() {
         });
         
         return resp.checkAndReturn();
         
	}




	/* (non-Javadoc)
	 * @see com.axin.service.OrderService#submitcancel(com.axin.common.entity.ApiToken, java.lang.Integer, java.lang.String, java.lang.String)
	 */
	@Override
	public BatchcancelResult submitcancel(ApiToken token, Integer accountId, String symbol, String side) {
		if(accountId == null){
			throw new ParamIllegalException("account-id is null");
		}
		Map<String, Object> parameterMap = new HashMap<>();
        parameterMap.put("account-id", accountId);
        if(StringUtils.isNotEmpty(symbol)){
        	parameterMap.put("symbol", symbol);
        }
        if(StringUtils.isNotEmpty(side)){
        	 parameterMap.put("side", side);
        }
        BatchcancelResponse<BatchcancelResult> resp =
       		 			httpRequest.post(token,API_ORDER_CANCELORDERS_URL, parameterMap, 
       		 							new TypeReference<BatchcancelResponse<BatchcancelResult>>() {});
        return resp.checkAndReturn();
	}
	
	
	
	
	
	
	
	
	
	
	
	

}
